home *** CD-ROM | disk | FTP | other *** search
/ The Games Machine 80 / XENIATGM80.iso / Goodies / Blood 2 / Source / data.z / BloodSplatFX.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-04-02  |  5.6 KB  |  218 lines

  1. // ----------------------------------------------------------------------- //
  2. //
  3. // MODULE  : BloodSplatFX.cpp
  4. //
  5. // PURPOSE : Blood splat special FX - Implementation
  6. //
  7. // CREATED : 10/13/97
  8. //
  9. // ----------------------------------------------------------------------- //
  10.  
  11. #include "BloodSplatFX.h"
  12. #include "cpp_client_de.h"
  13. #include "dlink.h"
  14. #include "BloodClientShell.h"
  15. #include "ClientUtilities.h"
  16.  
  17. #define REGION_DIAMETER            100.0f  // Squared distance actually
  18. #define MAX_SPLATS_IN_REGION    10
  19.  
  20. DList CBloodSplatFX::m_BloodSplatList =
  21. {
  22.     0,
  23.     { DNULL, DNULL, DNULL }
  24. };
  25.  
  26. // ----------------------------------------------------------------------- //
  27. //
  28. //    ROUTINE:    CBloodSplatFX::Init
  29. //
  30. //    PURPOSE:    Create the mark
  31. //
  32. // ----------------------------------------------------------------------- //
  33.  
  34. DBOOL CBloodSplatFX::Init(SFXCREATESTRUCT* psfxCreateStruct)
  35. {
  36.     if (!psfxCreateStruct) return DFALSE;
  37.  
  38.     CSpecialFX::Init(psfxCreateStruct);
  39.  
  40.     BSCREATESTRUCT* pMark = (BSCREATESTRUCT*)psfxCreateStruct;
  41.  
  42.     VEC_COPY(m_vPos, pMark->m_Pos);
  43.     ROT_COPY( m_Rotation, pMark->m_Rotation );
  44.     VEC_SET( m_vScale, pMark->m_fScale, pMark->m_fScale, pMark->m_fScale );
  45.     m_fGrowScale = pMark->m_fGrowScale;
  46.  
  47.     if( m_hstrSprite )
  48.         g_pClientDE->FreeString( m_hstrSprite );
  49.     m_hstrSprite = g_pClientDE->CopyString( pMark->m_hstrSprite );
  50.  
  51.     if(m_fGrowScale)
  52.         m_fGrowTime = 4.0f;
  53.     else
  54.         m_fGrowTime = 0.0f;
  55.  
  56.     m_bShrink = DFALSE;
  57.  
  58.     return DTRUE;
  59. }
  60.  
  61. // ----------------------------------------------------------------------- //
  62. //
  63. //    ROUTINE:    CBloodSplatFX::Term
  64. //
  65. //    PURPOSE:    Term
  66. //
  67. // ----------------------------------------------------------------------- //
  68.  
  69. DBOOL CBloodSplatFX::Term()
  70. {
  71.     m_bShrink = DTRUE;
  72.     m_fGrowTime = 0.0f;
  73.  
  74.     return DFALSE;
  75. }
  76.  
  77. // ----------------------------------------------------------------------- //
  78. //
  79. //    ROUTINE:    CBloodSplatFX::CreateObject
  80. //
  81. //    PURPOSE:    Create object associated with the mark
  82. //
  83. // ----------------------------------------------------------------------- //
  84.  
  85. DBOOL CBloodSplatFX::CreateObject(CClientDE *pClientDE)
  86. {
  87.     DLink *pCur;
  88.     CBloodSplatFX *pSplat;
  89.  
  90.     if (!CSpecialFX::CreateObject(pClientDE)) return DFALSE;
  91.  
  92.     // Before we create a new bloodsplat see if there is already another
  93.     // one close by that we could use instead...
  94.  
  95.     HOBJECT hMoveObj         = DNULL;
  96.     HOBJECT hObj             = DNULL;
  97.     DFLOAT    fClosestDist     = REGION_DIAMETER;
  98.     DBYTE    nNumInRegion     = 0;
  99.     DVector vPos;
  100.  
  101.     pCur = m_BloodSplatList.m_Head.m_pNext;
  102.     while( pCur != &m_BloodSplatList.m_Head )
  103.     {
  104.         pSplat = ( CBloodSplatFX * )pCur->m_pData;
  105.         pCur = pCur->m_pNext;
  106.  
  107.         if( pSplat && pSplat != this )
  108.         {
  109.             hObj = pSplat->GetObject();
  110.             if (hObj)
  111.             {
  112.                 pClientDE->GetObjectPos(hObj, &vPos);
  113.                 
  114.                 DFLOAT fDist = VEC_DISTSQR(vPos, m_vPos);
  115.                 if (fDist < REGION_DIAMETER)
  116.                 {
  117.                     if (fDist < fClosestDist)
  118.                     {
  119.                         fClosestDist = fDist;
  120.                         hMoveObj = hObj;
  121.                     }
  122.  
  123.                     if (++nNumInRegion > MAX_SPLATS_IN_REGION)
  124.                     {
  125.                         // Just move this bullet-hole to the correct pos, and
  126.                         // remove thyself...
  127.  
  128.                         pClientDE->SetObjectPos(hMoveObj, &m_vPos);
  129.                         return DFALSE;
  130.                     }
  131.                 }
  132.             }
  133.         }
  134.     }
  135.  
  136.     if(m_hServerObject)
  137.         pClientDE->GetObjectPos(m_hServerObject, &m_vPos);
  138.  
  139.     if (!m_hstrSprite)
  140.     {
  141.         switch(GetRandom(1,3))
  142.         {
  143.             case 1:        m_hstrSprite = pClientDE->CreateString("sprites\\blood1.spr");    break;
  144.             case 2:        m_hstrSprite = pClientDE->CreateString("sprites\\blood2.spr");    break;
  145.             case 3:        m_hstrSprite = pClientDE->CreateString("sprites\\blood3.spr");    break;
  146.             default:    m_hstrSprite = pClientDE->CreateString("sprites\\blood1.spr");    break;
  147.         }
  148.     }
  149.  
  150.     // Setup the mark...
  151.     ObjectCreateStruct createStruct;
  152.     INIT_OBJECTCREATESTRUCT(createStruct);
  153.  
  154.     createStruct.m_ObjectType = OT_SPRITE;
  155.     _mbscpy((unsigned char*)createStruct.m_Filename, (const unsigned char*)m_pClientDE->GetStringData( m_hstrSprite ));
  156.     createStruct.m_Flags      = FLAG_VISIBLE | FLAG_ROTATEABLESPRITE;
  157.     VEC_COPY(createStruct.m_Pos, m_vPos);
  158.     ROT_COPY( createStruct.m_Rotation, m_Rotation );
  159.  
  160.     m_hObject = pClientDE->CreateObject(&createStruct);
  161.  
  162.     m_pClientDE->SetObjectScale(m_hObject, &m_vScale);
  163.     m_pClientDE->SetObjectColor(m_hObject, 0.1f, 0.1f, 0.1f, 1.0f);
  164.  
  165.     return DTRUE;
  166. }
  167.  
  168.  
  169. // ----------------------------------------------------------------------- //
  170. //
  171. //    ROUTINE:    CBloodSplatFX::Update
  172. //
  173. //    PURPOSE:    Update the mark
  174. //
  175. // ----------------------------------------------------------------------- //
  176.  
  177. DBOOL CBloodSplatFX::Update()
  178. {
  179.     if(!m_hObject || !m_pClientDE) return DFALSE;
  180.  
  181.     DFLOAT fDelta = m_pClientDE->GetFrameTime();
  182.     if (fDelta > 0.25f) fDelta = 0.25f;
  183.  
  184.     if(m_fGrowScale && m_fGrowTime > 0 && !m_bShrink)
  185.     {
  186.         DFLOAT fScale = m_fGrowScale * fDelta * 30.0f;
  187.         m_vScale.x *= GetRandom(1.0f,1.0f + fScale * fDelta);
  188.         m_vScale.y *= GetRandom(1.0f,1.0f + fScale * fDelta);
  189.         m_vScale.z *= GetRandom(1.0f,1.0f + fScale * fDelta);
  190.         
  191.         m_pClientDE->SetObjectScale(m_hObject, &m_vScale);
  192.         m_fGrowTime -= fDelta;
  193.     }
  194.     else if(m_bShrink)
  195.     {
  196.         if(m_fGrowTime >= 5.0f)
  197.             return DFALSE;
  198.  
  199.         DFLOAT fAlpha = 0.0f;
  200.         DVector vColor;
  201.  
  202.         if(m_fGrowScale)
  203.         {
  204.             DFLOAT fScale = m_fGrowScale * fDelta * 30.0f;
  205.             m_vScale.x *= GetRandom(1.0f - fScale,1.0f);
  206.             m_vScale.y *= GetRandom(1.0f - fScale,1.0f);
  207.             m_vScale.z *= GetRandom(1.0f - fScale,1.0f);
  208.  
  209.             m_pClientDE->SetObjectScale(m_hObject, &m_vScale);
  210.         }
  211.         
  212.         m_pClientDE->GetObjectColor(m_hObject,&vColor.x, &vColor.y, &vColor.z, &fAlpha);
  213.         m_pClientDE->SetObjectColor(m_hObject,vColor.x,vColor.y,vColor.z,1.0f - (m_fGrowTime/5.0f));
  214.         m_fGrowTime += m_pClientDE->GetFrameTime();
  215.     }
  216.  
  217.     return DTRUE;
  218. }